/**************************************************************************
Step 1. Include necessary header files such that the stuff your test logic needs is declared. 
Don't forget gtest.h, which declares the testing framework.                                                   
**************************************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "gtest/gtest.h"
#include "include/pf_json.h"


/**************************************************************************
Step 2. Use test fixture to design your complex cases. 
You can add SetUp() to initialize the test data and 
TearDown() to clear the test data for common usage
Pls remember that when you using test fixture, need to use macro "TEST_F" instead of "TEST"                                                 
**************************************************************************/
class PfJsonTest : public testing::Test 
{
    /* This SetUp() will be called before every TEST CASE which is marked by macro "TEST_F" */
    virtual void SetUp() 
    {
    }
    /* This TearDown will be called after every TEST CASE which is marked by macro "TEST_F" */
    virtual void TearDown() 
    {

    }

public:

};

typedef struct json_arg
  {
      char* key[5];
      char* value[5];
      int i;
  } json_arg_t;

int json_print_test(void* arg, char *key, struct pf_json_object* val)
{
    json_arg_t* arg1 = (json_arg_t*)arg;
    EXPECT_STREQ(key, arg1->key[arg1->i]);
    EXPECT_STREQ(pf_json_obj_to_json_str(val), arg1->value[arg1->i]);
    arg1->i++;
    if(arg1->i >= 5)
    {
        return -1;
    }
    return 0;
}


/***************************************************************************
Step 3. Use macro "TEST_F" to start your test case                                      
You can design your test case as the example
***************************************************************************/
TEST_F(PfJsonTest, JsonCreateTest)
{
  pf_json_object_t* my_string_obj = NULL;
  pf_json_object_t* my_int_obj = NULL;
  pf_json_object_t* my_int64_obj = NULL;
  pf_json_object_t* my_double_obj = NULL;
  pf_json_object_t* my_bool_obj = NULL;
  pf_json_object_t* my_array_obj = NULL;
  pf_json_object_t* my_object_obj = NULL;
  pf_json_object_t* obj = NULL;
  const char* test_str = NULL;
  int test_int = 0;
  int is_debug = 0;
  int64_t test_int64 = 0;
  double test_double = 0.0;
  int len = 0;

  PF_JSON_SET_DEBUG(1);
  is_debug = PF_JSON_GET_DEBUG();
  EXPECT_EQ(is_debug, 1);

  my_string_obj = pf_json_create_str_obj("\t"); 
  test_str = pf_json_get_str(my_string_obj);
  EXPECT_STREQ(test_str, "\t");
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"\\t\"");
  pf_json_put_obj(my_string_obj);
  //pf_json_put_obj(my_string_obj);

  my_string_obj = pf_json_create_str_obj("\\"); 
  test_str = pf_json_get_str(my_string_obj);
  EXPECT_STREQ(test_str, "\\");
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"\\\\\""); 
  pf_json_put_obj(my_string_obj);

  my_string_obj = pf_json_create_str_obj("aa\007bb"); 
  test_str = pf_json_get_str(my_string_obj);
  EXPECT_STREQ(test_str, "aa\007bb");
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"aa\\u0007bb\""); 
  pf_json_put_obj(my_string_obj);

  my_string_obj = pf_json_create_str_obj("/aabb"); 
  test_str = pf_json_get_str(my_string_obj);
  EXPECT_STREQ(test_str, "/aabb");
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"\\/aabb\""); 
  pf_json_put_obj(my_string_obj);

  //my_string_obj = pf_json_create_str_obj("\/aabb"); 
  //test_str = pf_json_get_str(my_string_obj);
  //EXPECT_STREQ(test_str, "/aabb");
  //test_str = pf_json_obj_to_json_str(my_string_obj);
  //EXPECT_STREQ(test_str, "\"\\/aabb\""); 
  //pf_json_put_obj(my_string_obj);

  my_string_obj = pf_json_create_str_obj("1111111foo");
  test_str = pf_json_get_str(my_string_obj); 
  EXPECT_STREQ(test_str, "1111111foo"); 
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"1111111foo\"");  
  EXPECT_EQ(pf_json_get_int(my_string_obj), 1111111);
  pf_json_put_obj(my_string_obj); 

  my_string_obj = pf_json_create_str_obj("    000111111111111111111");
  test_str = pf_json_get_str(my_string_obj); 
  EXPECT_STREQ(test_str, "    000111111111111111111"); 
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"    000111111111111111111\"");  
  EXPECT_EQ(pf_json_get_int(my_string_obj), INT32_MAX);
  pf_json_put_obj(my_string_obj); 

  my_string_obj = pf_json_create_str_obj("-0111111111111111111");
  test_str = pf_json_get_str(my_string_obj); 
  EXPECT_STREQ(test_str, "-0111111111111111111"); 
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"-0111111111111111111\"");  
  EXPECT_EQ(pf_json_get_int(my_string_obj), INT32_MIN);
  EXPECT_EQ(pf_json_get_int64(my_string_obj), -111111111111111111);
  EXPECT_DOUBLE_EQ(pf_json_get_double(my_string_obj), -111111111111111111.0);
  pf_json_put_obj(my_string_obj); 


  my_string_obj = pf_json_create_str_obj("-0");
  EXPECT_EQ(pf_json_get_int64(my_string_obj), 0);
  pf_json_put_obj(my_string_obj);

  my_string_obj = pf_json_create_str_obj("223372036854775807");
  EXPECT_EQ(pf_json_get_int64(my_string_obj), 223372036854775807);
  pf_json_put_obj(my_string_obj);

  my_string_obj = pf_json_create_str_obj("11111111111111111111111111223372036854775807");
  EXPECT_EQ(pf_json_get_int64(my_string_obj), INT64_MAX);
  pf_json_put_obj(my_string_obj);
  
  my_string_obj = pf_json_create_str_len_obj("fooaaaaaaaaaaaa", 10);
  test_str = pf_json_get_str(my_string_obj); 
  EXPECT_STREQ(test_str, "fooaaaaaaa"); 
  test_str = pf_json_obj_to_json_str(my_string_obj);
  EXPECT_STREQ(test_str, "\"fooaaaaaaa\"");  
  EXPECT_EQ(pf_json_get_bool(my_string_obj), true);
  EXPECT_EQ(pf_json_get_int(my_string_obj), 0);
  EXPECT_EQ(pf_json_get_int64(my_string_obj), 0);
  EXPECT_DOUBLE_EQ(pf_json_get_double(my_string_obj), 0.0);

  len = pf_json_get_str_len(my_string_obj);
  EXPECT_EQ(len, 10);
  pf_json_put_obj(my_string_obj); 

  my_int_obj = pf_json_create_int_obj(9);
  test_int = pf_json_get_int(my_int_obj);
  EXPECT_EQ(test_int, 9);
  test_str = pf_json_obj_to_json_str(my_int_obj);
  EXPECT_STREQ(test_str, "9");
  EXPECT_EQ(pf_json_get_bool(my_int_obj), true);
  EXPECT_EQ(pf_json_get_int64(my_int_obj), 9);
  EXPECT_DOUBLE_EQ(pf_json_get_double(my_int_obj), 9.0);
  pf_json_put_obj(my_int_obj);

  my_int64_obj = pf_json_create_int64_obj(INT64_MAX);
  test_int64 = pf_json_get_int64(my_int64_obj);
  EXPECT_EQ(test_int64, INT64_MAX);
  test_str = pf_json_obj_to_json_str(my_int64_obj);
  EXPECT_STREQ(test_str, "9223372036854775807");
  EXPECT_EQ(pf_json_get_bool(my_int64_obj), true);
  EXPECT_DOUBLE_EQ(pf_json_get_double(my_int64_obj), 9223372036854775807.0);
  pf_json_put_obj(my_int64_obj);


  my_double_obj = pf_json_create_double_obj(9.123456);
  test_double = pf_json_get_double(my_double_obj);
  EXPECT_DOUBLE_EQ(test_double, 9.123456);
  test_str = pf_json_obj_to_json_str(my_double_obj);
  EXPECT_STREQ(test_str, "9.123456");
  EXPECT_EQ(pf_json_get_bool(my_double_obj), true);
  EXPECT_EQ(pf_json_get_int(my_double_obj), 9);
  EXPECT_EQ(pf_json_get_int64(my_double_obj), 9);
  pf_json_put_obj(my_double_obj);


  my_bool_obj = pf_json_create_bool_obj(true);
  test_str = pf_json_get_str(my_bool_obj);
  EXPECT_STREQ(test_str, "true");
  test_str = pf_json_obj_to_json_str(my_bool_obj);
  EXPECT_STREQ(test_str, "true");
  EXPECT_EQ(pf_json_get_bool(my_bool_obj), true);
  EXPECT_EQ(pf_json_get_int(my_bool_obj), 1);
  EXPECT_EQ(pf_json_get_int64(my_bool_obj), 1);
  EXPECT_DOUBLE_EQ(pf_json_get_double(my_bool_obj), 1.0);
  pf_json_put_obj(my_bool_obj);

  my_array_obj = pf_json_create_array_obj();
  pf_json_array_obj_add_item(my_array_obj,pf_json_create_int_obj(1));
  pf_json_array_obj_add_item(my_array_obj,pf_json_create_int_obj(2));
  pf_json_array_obj_add_item(my_array_obj,pf_json_create_int_obj(3));
  pf_json_array_obj_add_item(my_array_obj,pf_json_create_int_obj(5));
  len = pf_json_get_str_len(my_array_obj);
  EXPECT_EQ(len, 0);

  EXPECT_EQ(pf_json_array_obj_len(my_array_obj), 4);
  obj = pf_json_array_obj_get_item(my_array_obj, 0);
  EXPECT_STREQ(pf_json_obj_to_json_str(obj), "1");
  obj = pf_json_array_obj_get_item(my_array_obj, 1);
  EXPECT_STREQ(pf_json_obj_to_json_str(obj), "2");
  obj = pf_json_array_obj_get_item(my_array_obj, 2);
  EXPECT_STREQ(pf_json_obj_to_json_str(obj), "3");
  obj = pf_json_array_obj_get_item(my_array_obj, 3);
  EXPECT_STREQ(pf_json_obj_to_json_str(obj), "5");
  test_str = pf_json_obj_to_json_str(my_array_obj);
  EXPECT_STREQ(test_str, "[ 1, 2, 3, 5 ]");

  pf_json_array_obj_put_item(my_array_obj, 4, pf_json_create_int_obj(8));
  EXPECT_EQ(pf_json_array_obj_len(my_array_obj), 5);
  test_str = pf_json_obj_to_json_str(my_array_obj);
  EXPECT_STREQ(test_str, "[ 1, 2, 3, 5, 8 ]");

  

  //pf_json_put_obj(my_array_obj);

  my_object_obj = pf_json_create_obj();
  pf_json_add_sub_obj(my_object_obj, "abc",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "foo", pf_json_create_str_obj("bar"));
  pf_json_add_sub_obj(my_object_obj, "bool0", pf_json_create_bool_obj(0));
  pf_json_add_sub_obj(my_object_obj, "bool1", pf_json_create_bool_obj(1));
  pf_json_add_sub_obj(my_object_obj, "baz", pf_json_create_str_obj("bang"));
  pf_json_add_sub_obj(my_object_obj, "baz", pf_json_create_str_obj("fark"));
  pf_json_del_sub_obj(my_object_obj, "baz");
  pf_json_add_sub_obj(my_object_obj, "arr", my_array_obj);
  test_str = pf_json_obj_to_json_str(my_object_obj);
  EXPECT_STREQ(test_str, "{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, 5, 8 ] }");
  json_arg_t args;
  args.i = 0;
  args.key[0] = "abc";
  args.value[0] = "12";
  args.key[1] = "foo";
  args.value[1] = "\"bar\"";
  args.key[2] = "bool0";
  args.value[2] = "false";
  args.key[3] = "bool1";
  args.value[3] = "true";
  args.key[4] = "arr";
  args.value[4] = "[ 1, 2, 3, 5, 8 ]";
  pf_json_obj_for_each(my_object_obj, (void*)&args, json_print_test);

  pf_json_add_sub_obj(my_object_obj, "abc1",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc2",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc3",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc4",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc5",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc6",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc7",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc8",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc9",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc10",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc11",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc12",pf_json_create_int_obj(12));
  pf_json_add_sub_obj(my_object_obj, "abc13",pf_json_create_int_obj(12));

  test_str = pf_json_obj_to_json_str(my_object_obj);
  EXPECT_STREQ(test_str, "{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, 5, 8 ], \"abc1\": 12, \"abc2\": 12, \"abc3\": 12, \"abc4\": 12, \"abc5\": 12, \"abc6\": 12, \"abc7\": 12, \"abc8\": 12, \"abc9\": 12, \"abc10\": 12, \"abc11\": 12, \"abc12\": 12, \"abc13\": 12 }");

  pf_json_array_obj_put_item(my_array_obj, 32, pf_json_create_int_obj(100));
  EXPECT_EQ(pf_json_array_obj_len(my_array_obj), 33);
  test_str = pf_json_obj_to_json_str(my_array_obj);
  EXPECT_STREQ(test_str, "[ 1, 2, 3, 5, 8, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 100 ]");

  pf_json_put_obj(my_object_obj);

} 

TEST_F(PfJsonTest, JsonParseTest)
{
    pf_json_object_t* new_obj = NULL;
    pf_json_object_t* sub_obj = NULL;
    const char* test_str = NULL;
    char* mybuf = NULL;
    pf_json_tokener_t* tok = NULL;
    pf_json_tokener_error_e error;

    new_obj = pf_json_parse("\"\003\"");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "\"\\u0003\"");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("/* hello */\"foo\"");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "\"foo\"");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("// hello\n\"foo\"");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "\"foo\"");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("/a hello\n\"foo\"");
    EXPECT_EQ(new_obj, (void*)NULL);

    new_obj = pf_json_parse("/* hello\n\"foo\"");
    EXPECT_EQ(new_obj, (void*)NULL);

    new_obj = pf_json_parse("//hello\"foo\"\n");
    EXPECT_EQ(new_obj, (void*)NULL);

    new_obj = pf_json_parse("/*hello*\"foo\"\n");
    EXPECT_EQ(new_obj, (void*)NULL);

    new_obj = pf_json_parse("\"\\u0041\\u0042\\u0043\"");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "\"ABC\"");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("null");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "null");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("True");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "true");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("12");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "12");  
    pf_json_put_obj(new_obj);
    
    new_obj = pf_json_parse("   9223372036854775807");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "9223372036854775807");  
    pf_json_put_obj(new_obj);


    new_obj = pf_json_parse("12.3");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "12.300000");  
    pf_json_put_obj(new_obj);


    new_obj = pf_json_parse("[\"\\nabc\\n\"]");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "[ \"\\nabc\\n\" ]");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("[null]");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "[ null ]");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("[]");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "[ ]");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("[\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"]");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "[ \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" ]");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("[false]");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "[ false ]");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("[\"abc\",null,\"def\",12]");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "[ \"abc\", null, \"def\", 12 ]");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("{}");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ }");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("{ \"foo\": \"bar\" }");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ \"foo\": \"bar\" }");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("{ \"foo\": [null, \"foo\"] }");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ \"foo\": [ null, \"foo\" ] }");  
    pf_json_put_obj(new_obj);

    new_obj = pf_json_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");  
    sub_obj = pf_json_get_sub_obj(new_obj, "arr");
    EXPECT_NE(sub_obj, (void*)NULL);
    test_str = pf_json_obj_to_json_str(sub_obj);
    EXPECT_STREQ(test_str, "[ 1, 2, 3, null, 5 ]");
    pf_json_put_obj(new_obj);

    error = PF_JSON_TOK_SUCCESS;  
    new_obj = pf_json_parse_verbose("{ foo }", &error);
    EXPECT_EQ(error, PF_JSON_TOK_ERR_PARSE_OBJECT_KEY_NAME);
    EXPECT_EQ(new_obj, (void*)NULL);

    new_obj = pf_json_parse("{ foo }");
    EXPECT_EQ(new_obj, (void*)NULL);
  
    new_obj = pf_json_parse("foo");
    EXPECT_EQ(new_obj, (void*)NULL);
    new_obj = pf_json_parse_verbose("foo", &error);
    EXPECT_EQ(new_obj, (void*)NULL);
    EXPECT_EQ(error, PF_JSON_TOK_ERR_PARSE_BOOLEAN);

    new_obj = pf_json_parse("{ \"foo");
    EXPECT_EQ(new_obj, (void*)NULL);


    /* test incremental parsing */
    tok = pf_json_create_tokener();
    new_obj = pf_json_parse_ex(tok, "{ \"foo", 6);
    EXPECT_EQ(new_obj, (void*)NULL);
    new_obj = pf_json_parse_ex(tok, "\": {\"bar", 8);
    EXPECT_EQ(new_obj, (void*)NULL);
    new_obj = pf_json_parse_ex(tok, "\":13}}", 6);
    EXPECT_NE(new_obj, (void*)NULL);
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ \"foo\": { \"bar\": 13 } }");
    EXPECT_EQ(pf_json_is_obj_type(new_obj, PF_JSON_TYPE_OBJECT), 1);
    EXPECT_EQ(pf_json_is_obj_type(new_obj, PF_JSON_TYPE_ARRAY), 0);
    EXPECT_EQ(pf_json_get_obj_type(new_obj), PF_JSON_TYPE_OBJECT);
    pf_json_put_obj(new_obj);

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": true}", 8);
    EXPECT_NE(new_obj, (void*)NULL);   
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ \"food\": true }");
    pf_json_put_obj(new_obj);

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": xrue}", 8);
    EXPECT_EQ(new_obj, (void*)NULL);   

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    mybuf = "\" //aaaa:true}";
    new_obj = pf_json_parse_ex(tok, mybuf, strlen(mybuf));
    EXPECT_EQ(new_obj, (void*)NULL);   

    
    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": nullaabb}", 11);
    EXPECT_EQ(new_obj, (void*)NULL);   

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": \"aa\\r\\t\"}", 12);
    EXPECT_NE(new_obj, (void*)NULL);   
    pf_json_put_obj(new_obj);

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"\\nfood", 9);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": \"aa\\r\\t\"}", 12);
    EXPECT_NE(new_obj, (void*)NULL);   
    pf_json_put_obj(new_obj);

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"\\nfood", 9);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\", \"aa\\r\\t\"}", 12);
    EXPECT_EQ(new_obj, (void*)NULL);   

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"\\nfood", 9);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":true}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}", 263); 
    EXPECT_EQ(new_obj, (void*)NULL); 

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": \"aa\\\\t\"}", 11);
    EXPECT_NE(new_obj, (void*)NULL);   
    pf_json_put_obj(new_obj);

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": \"aa\\r\\t\\z\"}", 12);
    EXPECT_EQ(new_obj, (void*)NULL);   

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\"aa\", true]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}", 77);
    EXPECT_EQ(new_obj, (void*)NULL);   

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\"aa\". true]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}", 73);
    EXPECT_EQ(new_obj, (void*)NULL);   


    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    new_obj = pf_json_parse_ex(tok, "\": \"aa\\u11dc00\\u0041\\u0082\\ud800\\u11dc00\\u110001\\uf10001\"}", 32+8+2+8+8);
    EXPECT_NE(new_obj, (void*)NULL);   
    pf_json_put_obj(new_obj);

    pf_json_reset_tokener(tok);
    new_obj = pf_json_parse_ex(tok, "{ \"food", 7);
    EXPECT_EQ(new_obj, (void*)NULL);   
    mybuf = "\": \"aa\\u0041\\u0082\\ud800\\udc00\\u0051\\u0057\\u0113\\u0117\\u0114\\u0113\\u0052\\u0051\\u0048\\u0057\\u0106\\u0106\\u0097\\u0106\\u0042\\u0038\\u0094\\u0037\\u0036\\u0035\\u0036\\u0033\\u0033\\u0083\\u0102\\u0097\\u0105\\u0101\\u0106\\u0102\\u0106\\u0108\\u0097\\u00106\\u00102\\u00108\\u0097\\u0106\\u0095\\u0043\\u0043\\u0124\\uff0124\\uffff0124\\u0000\\u007f\\u001fffff\\u7ffffff\", \"one\":true}",
    new_obj = pf_json_parse_ex(tok, mybuf, strlen(mybuf));
    EXPECT_NE(new_obj, (void*)NULL);   
    pf_json_put_obj(new_obj);



    pf_json_destroy_tokener(tok);

    EXPECT_STREQ(pf_json_obj_type_to_name(PF_JSON_TYPE_ARRAY), "array");
    EXPECT_STREQ(pf_json_obj_type_to_name(PF_JSON_TYPE_NULL), "null");
    EXPECT_STREQ(pf_json_obj_type_to_name(PF_JSON_TYPE_BOOLEAN), "boolean");
    EXPECT_STREQ(pf_json_obj_type_to_name(PF_JSON_TYPE_DOUBLE), "double");
    EXPECT_STREQ(pf_json_obj_type_to_name(PF_JSON_TYPE_INT), "int");
    EXPECT_STREQ(pf_json_obj_type_to_name(PF_JSON_TYPE_OBJECT), "object");
    EXPECT_STREQ(pf_json_obj_type_to_name(PF_JSON_TYPE_STRING), "string");
}

TEST_F(PfJsonTest, JsonExtraTest)
{
    pf_json_tokener_t* tok = NULL;
    pf_json_object_t* new_obj = NULL;
    pf_json_object_t* file_obj = NULL;
    const char* test_str = NULL;
    int ret = 0;

    tok = pf_json_create_tokener();
    EXPECT_NE(tok, (void*)NULL);
    pf_json_destroy_tokener(tok);
    tok = NULL;
    EXPECT_EQ(tok, (void*)NULL);
    pf_json_reset_tokener(tok);
    EXPECT_EQ(tok, (void*)NULL);

    new_obj = pf_json_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");
    test_str = pf_json_obj_to_json_str(new_obj);
    EXPECT_STREQ(test_str, "{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }"); 

    ret = pf_json_obj_to_file("./new_obj.file", new_obj);
    EXPECT_EQ(ret, 0);

    file_obj = pf_json_create_obj_from_file("./new_obj.file");
    EXPECT_NE(file_obj, (void*)NULL);
    test_str = pf_json_obj_to_json_str(file_obj);
    EXPECT_STREQ(test_str, "{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }"); 

    unlink("./new_obj.file");
    pf_json_put_obj(new_obj);
    pf_json_put_obj(file_obj);

    ret = pf_json_obj_to_file("./new_obj.file", NULL);
    EXPECT_NE(ret, 0);
    ret = pf_json_obj_to_file("./aabbccdd/new_obj.file", new_obj);
    EXPECT_NE(ret, 0);

    file_obj = pf_json_create_obj_from_file("./aabbccdd/new_obj.file");
    EXPECT_EQ(file_obj, (void*)NULL);
}
